using System;
using System.Windows.Forms;
using FireStarterModeller.BO;
using FireStarterModeller.Test.BO;
using FireStarterModeller.UI;
using Habanero.Base;
using Habanero.Base.Exceptions;
using Habanero.BO;
using Habanero.Faces.Test.Win.Selectors;
using Habanero.Faces.Base;
using NUnit.Framework;

namespace FireStarterModeller.Test.UI
{
    /// <summary>
    /// This control implements the IBOSelector Interface and should therefore fulfill the interface
    /// </summary>
    [TestFixture]
    public class TestDMRelationshipSelector_AsBOSelector : TestReadOnlyGridControlSelectorWin
    {
        [TestFixtureSetUp]
        public void SetupFixture()
        {
            UITestUtils.SetupFixture();
        }


        [SetUp]
        public virtual void SetupTest()
        {
            UITestUtils.SetupTest();

        }
        protected override int NumberOfLeadingBlankRows()
        {
            return 1;
        }

        protected override int ActualIndex(int index)
        {
            return index ;
        }
        protected override int ActualNumberOfRows(int noOfBOs)
        {
            return noOfBOs + NumberOfLeadingBlankRows() + NumberOfTrailingBlankRows();
        }
        protected override IBusinessObject CreateNewBO()
        {
            DMRelationship dmRelationship = new DMRelationship();
            dmRelationship.RelationshipName = TestUtilsShared.GetRandomString(10);
            return dmRelationship;
        }

        protected static DMRelationship CreateNewDMRelationship(string relationshipName)
        {
            DMRelationship dmRelationship = new DMRelationship();
            dmRelationship.RelationshipName = relationshipName;
            return dmRelationship;
        }

        protected override IBOColSelectorControl CreateSelector()
        {
            DMRelationshipSelectorControl selectorControl = new DMRelationshipSelectorControl(GetControlFactory());
            Form frm = new Form();
            frm.Controls.Add(selectorControl);
            return selectorControl;
        }
        protected override IBusinessObjectCollection GetCollectionWith_4_Objects()
        {
            DMRelationship bo = CreateNewDMRelationship("b");
            DMRelationship bo2 = CreateNewDMRelationship("d");
            DMRelationship bo3 = CreateNewDMRelationship("c");
            DMRelationship bo4 = CreateNewDMRelationship("a");
            return new BusinessObjectCollection<DMRelationship> { bo, bo2, bo3, bo4 };
        }
        protected override IBusinessObjectCollection GetCollectionWithNoItems()
        {
            return new BusinessObjectCollection<DMRelationship>();
        }

        protected override IBusinessObjectCollection GetCollectionWithOneBO(out IBusinessObject bo)
        {
            bo = CreateNewBO();
            return new BusinessObjectCollection<DMRelationship> { (DMRelationship)bo };
        }
        protected override IBusinessObjectCollection GetCollectionWithTowBOs(out IBusinessObject bo)
        {
            bo = CreateNewBO();
            DMRelationship bo2 = (DMRelationship)CreateNewBO();
            return new BusinessObjectCollection<DMRelationship> { (DMRelationship)bo, bo2 };
        }
        /// <summary>
        /// Need to solve getting the selectedIndex directly off the control necause this is causing
        /// me to expose GridControl all the time which means that the controls are not trully swappable.
        /// </summary>
        /// <param name="colSelector"></param>
        /// <param name="index"></param>
        protected override void SetSelectedIndex(IBOColSelectorControl colSelector, int index)
        {
            int count = 0;

            IGridBase gridSelector = ((DMRelationshipSelectorControl)colSelector).GridControl.Grid;
            foreach (IDataGridViewRow row in gridSelector.Rows)
            {
                if (row == null) continue; //This is done to stop the Pragma warning.
                if (count == index)
                {
                    IBusinessObject businessObjectAtRow = gridSelector.GetBusinessObjectAtRow(count);
                    colSelector.SelectedBusinessObject = businessObjectAtRow;
                }
                count++;
            }
        }

        protected override int SelectedIndex(IBOColSelectorControl colSelector)
        {
            IGridBase gridSelector = ((DMRelationshipSelectorControl)colSelector).GridControl.Grid;
            IDataGridViewRow currentRow = null;
            if (gridSelector.SelectedRows.Count > 0)
            {
                currentRow = gridSelector.SelectedRows[0];
            }

            if (currentRow == null) return -1;

            return gridSelector.Rows.IndexOf(currentRow);
        }


        [Test]
        public void Test_Constructor_nullControlFactory_RaisesError()
        {
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            try
            {
                new DMRelationshipSelectorControl(null);
                Assert.Fail("expected ArgumentNullException");
            }
            //---------------Test Result -----------------------
            catch (HabaneroArgumentException ex)
            {
                StringAssert.Contains("The argument 'controlFactory' is not valid", ex.Message);
                StringAssert.Contains
                    ("Cannot create an 'DMRelationshipSelectorControl' if the control factory is null", ex.Message);
            }
        }
        [Test]
        public override void Test_Constructor_ReadOnlyGridControlSet()
        {
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            IBOColSelectorControl colSelector = CreateSelector();
            //---------------Test Result -----------------------
            Assert.IsInstanceOf(typeof(DMRelationshipSelectorControl), colSelector);
        }

        [Test]
        public override void Test_AutoSelectsFirstItem_NoItems()
        {
            //---------------Set up test pack-------------------
            IBOColSelectorControl colSelector = CreateSelector();
            IBusinessObjectCollection collection = GetCollectionWithNoItems();
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, colSelector.NoOfItems);
            Assert.AreEqual(-1, SelectedIndex(colSelector));
            Assert.AreEqual(null, colSelector.SelectedBusinessObject);
            //---------------Execute Test ----------------------
            colSelector.BusinessObjectCollection = collection;
            //---------------Test Result -----------------------
            Assert.AreEqual(ActualNumberOfRows(0), colSelector.NoOfItems, "The blank item");
            Assert.AreSame(null, colSelector.SelectedBusinessObject);
            Assert.AreEqual(0, SelectedIndex(colSelector));
        }

        [Test]
        public override void Test_ResetBOCol_ToNullClearsItems()
        {
            //---------------Set up test pack-------------------
            IBOColSelectorControl colSelector = CreateSelector();
            IBusinessObject bo;
            IBusinessObjectCollection collection = GetCollectionWithOneBO(out bo);
            colSelector.BusinessObjectCollection = collection;
            //---------------Assert Precondition----------------
            Assert.AreEqual(ActualNumberOfRows(collection.Count), colSelector.NoOfItems, "The blank item and one other");
            Assert.AreSame(bo, colSelector.SelectedBusinessObject);
            //---------------Execute Test ----------------------
            colSelector.BusinessObjectCollection = null;
            //---------------Test Result -----------------------
            Assert.IsNull(colSelector.SelectedBusinessObject);
            Assert.IsNull(colSelector.BusinessObjectCollection);
            Assert.AreEqual(0, colSelector.NoOfItems, "The blank item");
        }

        [Test]
        public override void Test_SetAutoSelectFirstItem_ShouldChangeAutoSelection()
        {
            //---------------Set up test pack-------------------
            IBOColSelectorControl colSelector = CreateSelector();
            //---------------Assert Precondition----------------
            Assert.IsFalse(colSelector.AutoSelectFirstItem);
            //---------------Execute Test ----------------------
            colSelector.AutoSelectFirstItem = true;
            //---------------Test Result -----------------------
            Assert.IsTrue(colSelector.AutoSelectFirstItem);
        }


        [Test]
        public override void Test_SetBOCollection_WhenAutoSelectFalse_ShouldNot_AutoSelectsFirstItem()
        {
            //---------------Set up test pack-------------------
            IBOColSelectorControl colSelector = CreateSelector();
            IBusinessObject myBO;
            IBusinessObjectCollection collection = GetCollectionWithTowBOs(out myBO);
            colSelector.AutoSelectFirstItem = false;
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, colSelector.NoOfItems);
            Assert.AreEqual(-1, SelectedIndex(colSelector));
            Assert.AreEqual(null, colSelector.SelectedBusinessObject);
            Assert.IsFalse(colSelector.AutoSelectFirstItem);
            //---------------Execute Test ----------------------
            colSelector.BusinessObjectCollection = collection;
            //---------------Test Result -----------------------
            Assert.AreEqual(ActualNumberOfRows(collection.Count), colSelector.NoOfItems, "The blank item");
            Assert.IsNotNull(colSelector.SelectedBusinessObject);
   // This is a grid and has been implemented to always select the first item          Assert.IsNull(colSelector.SelectedBusinessObject);
        }
    }
}